package org.ReportDesigner.designerXML;

import org.ReportDesigner.reportModel.ReportElement;
import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

import java.util.Stack;

/**
 * класс  EventHandler расширяет класс  DefaultHandler библиотеки org.xml.sax.helpers.DefaultHandler
 * добавляя обработчики событий связанные со структурой нашего xml документа
 *
 *
 */


public class EventHandler extends DefaultHandler {

    /**
     * подключаем логер, для логирования ошибок
     */
    private static final Logger log = Logger.getLogger(EventHandler.class);



    private  Stack<ReportElement> stack;
    private static TypesMap tMap;
    private  ReportElement report;

    /**
     * оъекты инициализируемые при создании экземпляра класса
     * получаем карту классов
     */
    static {
        //получае карту классов из пакета reportModel
        tMap = new TypesMap();
    }

    public  ReportElement getReport() {
        return report;
    }

    public  void setReport(ReportElement report) {
        this.report = report;
    }

    /**
     *
     * @param uri
     * @param localName
     * @param qName  - имя тега
     * @param attributes - атрибуты xml тега
     */
    public void startElement(String uri, String localName,
                             String qName, Attributes attributes){

        //проверяем на вхождение
        if (tMap.inMap(qName)){
            //создаем новый экземпляр по ключу
            ReportElement reportElement = tMap.getNewElementByKey(qName);
            //добовляем в стек
            stack.add(reportElement);
        }
        else {
            try {
                throw new Exception("Do`nt contain key" + qName);
            } catch (Exception e) {
                log.error(e);
            }

        }


    }

    /**
     *
     * @param URI
     * @param localName
     * @param qName
     */
    public void endElement(String URI, String localName,
                           String qName){
        if (stack.size()>1){
            //возвращает верхний элемент с удалением его из стека
            ReportElement some = stack.pop();
            stack.peek().addBodyElement(some);
        }
        else {
            report = stack.peek();
        }


    }

    /**
     *
     * @param ch
     * @param start
     * @param length
     */
    public void characters(char ch[], int start, int length){
        if (!stack.empty()){
            if (stack.peek().getType().equalsIgnoreCase("text") ||
                    stack.peek().getType().equalsIgnoreCase("mixed")){
                stack.peek().setText(new String(ch, start,length));
            }
        }
    }

    public void startDocument(){
        stack = new Stack<ReportElement>();
        log.info("Sax parsing document started.");
    }


    public void endDocument(){
        log.info("Sax parsing document ended.");
    }
}
